package com.xh.utils;

import cn.hutool.core.util.StrUtil;
import com.xh.common.consts.RConst;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author wen
 * @apiNote ParamsUtil
 * @since 2022/11/28
 */
@Slf4j
public class ParamsUtil {

    public static AntPathMatcher matcher = new AntPathMatcher();

    public static final Pattern PATTERN = Pattern.compile("\\s*|\t|\r|\n");

    public static final int ERROR_MSG_MAX_LENGTH = 200;

    public static String getParams(HttpServletRequest request) {
        if (isMultipart(request)) {
            return request.getContentType() + ", contentLength:" + request.getContentLength();
        }
        String getParams = null;
        try {
            getParams = request.getQueryString() == null ? "" : URLDecoder.decode(request.getQueryString(), "UTF-8");
            byte[] byteArr = StreamUtils.copyToByteArray(request.getInputStream());
            String postParams = new String(byteArr, StandardCharsets.UTF_8);
            return "queryString:" + getParams + ", body:" + postParams;
        } catch (IOException e) {
            log.info("获取请求参数异常", e);
        }
        return getParams;
    }

    public static String getParamsWithJson(HttpServletRequest request) {
        if (isMultipart(request)) {
            return request.getContentType() + ", contentLength:" + request.getContentLength();
        }
        String getParams = null;
        try {
            getParams = request.getQueryString() == null ? "" : URLDecoder.decode(request.getQueryString(), "UTF-8");
            String body = getRequestBody(request);
            // 过滤掉\t \r \n
            Matcher m = PATTERN.matcher(body);
            body = m.replaceAll("");

            Map<String, Object> map = new HashMap<>(2);
            map.put("queryString", getParams);
            map.put("body", body);
            return JacksonUtil.toJson(map);
        } catch (IOException e) {
            log.info("获取请求参数异常", e);
        }
        return getParams;
    }

    public static boolean isMultipart(HttpServletRequest request) {
        if (!RConst.Str.CONST_POST.equalsIgnoreCase(request.getMethod())) {
            return false;
        }
        String contentType = request.getContentType();
        return StringUtils.startsWithIgnoreCase(contentType, "multipart/");
    }

    /**
     * 使用AntPathMatcher
     */
    public static boolean isMatch(String uri, Collection<String> uriPatterns) {
        if (CollectionUtils.isEmpty(uriPatterns)) {
            return false;
        }
        Iterator<String> iterator = uriPatterns.iterator();
        boolean flag;
        do {
            if (!iterator.hasNext()) {
                return false;
            }
            flag = matcher.match(iterator.next(), uri);
        } while (!flag);
        return true;
    }

    public static String substringErrorMsg(String errorMsg) {
        if (!StringUtils.hasText(errorMsg)) {
            return errorMsg;
        }
        if (errorMsg.length() > ERROR_MSG_MAX_LENGTH) {
            return errorMsg.substring(0, ERROR_MSG_MAX_LENGTH);
        }
        return errorMsg;
    }

    /**
     * 获取post参数
     *
     * @param request HttpServletRequest
     * @return String
     */
    private static String getRequestBody(HttpServletRequest request) {
        StringBuilder stringBuilder = new StringBuilder();
        try (InputStream inputStream = request.getInputStream()) {
            if (inputStream != null) {
                char[] charBuffer = new char[128];
                int bytesRead;
                try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
                    while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                        stringBuilder.append(charBuffer, 0, bytesRead);
                    }
                } catch (IOException ex) {
                    log.warn("记录请求的post参数，读取BufferReader流发生异常", ex);
                }
            }
        } catch (IOException e) {
            log.warn("记录请求的post参数，获取inputStream发生异常", e);
        }
        return stringBuilder.toString();
    }

    /**
     * 将url参数转换成map
     *
     * @param param aa=11&bb=22&cc=33
     */
    public static Map<String, Object> getUrlParams(String param) {
        Map<String, Object> map = new HashMap<>();
        if (StrUtil.isEmpty(param)) {
            return map;
        }
        String[] params = param.split("&");
        for (String s : params) {
            String[] p = s.split("=");
            if (p.length == 2) {
                map.put(p[0], p[1]);
            }
        }
        return map;
    }

    /**
     * 将map转换成url
     */
    public static String getQueryString(Map<String, Object> map) {
        if (map == null) {
            return RConst.Str.EMPTY;
        }
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            sb.append(entry.getKey()).append(RConst.Str.EQUALS).append(entry.getValue());
            sb.append(RConst.Str.AMPERSAND);
        }
        String s = sb.toString();
        if (s.endsWith(RConst.Str.AMPERSAND)) {
            s = StrUtil.subBefore(s, RConst.Str.AMPERSAND, true);
        }
        return s;
    }

}
